/**
* \file DGVBlitzArrayCaster.h
*
* \brief This file defines the class for casting Blitz++ arrays to and from Qt Images (QImage).
* \author Shekhar S. Chandra, 2008
*
* This file is part of DGV Library.
*
* DGV is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DGV is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with DGV.  If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef DGVBLITZARRAYCASTER_H
#define DGVBLITZARRAYCASTER_H

#include <QImage>

#include "DGVAliases.h"

/*!
    \class DGVBlitzArrayCaster
    \brief This class handles casting of Blitz++ Arrays to and from Qt objects.
    \author Shekhar S. Chandra, 2008

    Casts from and to Blitz++ Arrays and QImage objects. Stores the min, max and mean of the data also.
*/
template<typename type>
class DGV_TEMPLATEDLL DGVBlitzArrayCaster
{
public:
    DGVBlitzArrayCaster();
    virtual ~DGVBlitzArrayCaster();

    QImage* arrayToQImage(const Array<type,2> &data);
    void QImageToArray(QImage *image, Array<type,2> &newArray);

    inline type getMin()
    {   return min; }
    inline type getMax()
    {   return max; }
    inline type getMean()
    {   return mean;    }

protected:
    type min; //!< Minimum image value
	type max; //!< Maximum image value
	type mean; //!< Mean image value
};

template<typename type>
DGVBlitzArrayCaster<type>::DGVBlitzArrayCaster()
{
    //ctor
}

template<typename type>
DGVBlitzArrayCaster<type>::~DGVBlitzArrayCaster()
{
    //dtor
}

template<typename type>
QImage* DGVBlitzArrayCaster<type>::arrayToQImage(const Array<type,2> &data)
{
    QImage *image = new QImage(data.cols(),data.rows(),QImage::Format_Indexed8);
    type tmp;

    ///Find Max
    if(data.cols() > 0 && data.rows() > 0)
        min = max = data(0,0);

    for(int j = 0; j < data.rows(); j ++)
        for(int k = 0; k < data.cols(); k ++)
        {
            if(max < data(j,k))
                max = data(j,k);
            if(min > data(j,k))
                min = data(j,k);
        }
    qDebug() << "\nMax Pixel: " << max << ", Min Pixel: " << min;
    max -= min;

    ///Set colour table
    image->setNumColors(256);
    for(int j = 0; j < 256; j ++)
        image->setColor(j,qRgb(j, j, j));

    ///Scale values if required
    if(max > 255 || min < 0)
    {
        if(min < 0)
            max -= min;

        ///Scaling is required
        for(int j = 0; j < data.rows(); j ++)
            for(int k = 0; k < data.cols(); k ++)
            {
                tmp = static_cast<type>( (data(j,k)-min)/static_cast<double>(max)*255.0 );
                //cerr << " tmp: " << tmp << ", ";
                image->setPixel(k,j,static_cast<uint>(tmp));
            }
    }
    else
    {
        ///Copy across normally
        for(int j = 0; j < data.rows(); j ++)
            for(int k = 0; k < data.cols(); k ++)
                image->setPixel(k,j,static_cast<uint>(data(j,k)));
    }

    return image;
}

template<typename type>
void DGVBlitzArrayCaster<type>::QImageToArray(QImage *image, Array<type,2> &newArray)
{
    newArray.resize(image->height(),image->width());

    for(int j = 0; j < image->height(); j ++)
        for(int k = 0; k < image->width(); k ++)
            newArray(j,k) = qGray(image->pixel(k,j));
}

#endif // DGVBLITZARRAYCASTER_H
